package com.student.health.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.student.health.advice.ExceptionEnums;
import com.student.health.advice.MyException;
import com.student.health.dao.FoodsMapper;
import com.student.health.entity.CheckInfo;
import com.student.health.entity.Foods;
import com.student.health.entity.FoodsDetail;
import com.student.health.service.FoodsDetailService;
import com.student.health.service.FoodsService;
import com.student.health.utils.DTO.FoodsDaySuggestDataDTO;
import com.student.health.utils.Vo.FoodDetailVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class FoodsServiceImpl extends ServiceImpl<FoodsMapper, Foods> implements FoodsService{

    @Autowired
    private FoodsMapper foodsMapper;

    @Autowired
    private FoodsDetailService foodsDetailService;

    @Override
    public FoodsDaySuggestDataDTO getFoodDataAnalysis(CheckInfo currentCheckInfo) {
        if(currentCheckInfo == null ){
            throw new MyException(ExceptionEnums.NO_CHECK_INFO);
        }
        FoodsDaySuggestDataDTO foodsDaySuggestDataDTO = new FoodsDaySuggestDataDTO();
        //计算BMR
        //对于男性：BMR = 88.362 + (13.397 × 体重[kg]) + (4.799 × 身高[cm]) - (5.677 × 年龄[岁])
        //对于女性：BMR = 447.593 + (9.247 × 体重[kg]) + (3.098 × 身高[cm]) - (4.330 × 年龄[岁])
        double bmrValue = 0.0;
        if("女".equals(currentCheckInfo.getSex())){
            bmrValue =447.593 + (9.247 * currentCheckInfo.getWeight()) + (3.098 *currentCheckInfo.getHeight()) - (4.330 * currentCheckInfo.getRealAge());
        }
        if("男".equals(currentCheckInfo.getSex())){
            bmrValue = 88.362 + (13.397 * currentCheckInfo.getWeight()) + (4.799 * currentCheckInfo.getHeight()) - (5.677 * currentCheckInfo.getRealAge());
        }
        foodsDaySuggestDataDTO.setBmrValue(String.valueOf(Math.ceil(bmrValue)));

        int zhushilei = currentCheckInfo.getZhushiLei() * 21 / 1200;
        int roudanLei = currentCheckInfo.getRoudanLei()*21/ 1200;
        int dadouzhipinLei = currentCheckInfo.getDadouzhipinLei()*21 / 1200;
        int shucaijunzaoLei = currentCheckInfo.getShucaijunzaoLei()*21 / 1200;
        int shuiguoLei = currentCheckInfo.getShuiguoLei()*21 / 1200;
        int naiyoulei = currentCheckInfo.getNaiyouLei()*21 / 1200;
        int youzhiLei = currentCheckInfo.getYouzhiLei()*21 / 1200;
        int jianguoLei = currentCheckInfo.getJianguoLei()*21 / 1200;
        int tiaoweipinLei = currentCheckInfo.getTiaoweipinLei()*21 / 1200;
        int yinliaoLei = currentCheckInfo.getYinliaoLei()*21 / 1200;
        int lingshilengyinLei = currentCheckInfo.getLingshilengyinLei()*21 / 1200;
        int qitaLei = currentCheckInfo.getQitaLei()*21 / 1200;
        String bmiValue = currentCheckInfo.getBmiValue();
        double bmi = Double.parseDouble(bmiValue);
        if (bmi < 19) {
            //偏低
            zhushilei += 1;
            jianguoLei += 1;
            naiyoulei += 1;
            roudanLei += 1;
            shuiguoLei += 1;
        } else if (bmi < 25) {
           //正常
            shuiguoLei +=1;
            zhushilei +=1;
            shucaijunzaoLei += 1;
        } else if (bmi < 30) {
            //偏高
            dadouzhipinLei +=1;
            shucaijunzaoLei +=1;
            shuiguoLei +=1;
            jianguoLei +=1;
        } else if (bmi < 39) {
            //非常高
            dadouzhipinLei +=2;
            shucaijunzaoLei +=2;
            shuiguoLei +=2;
            jianguoLei +=2;
            yinliaoLei -=2;
            lingshilengyinLei -=2;
            naiyoulei -=2;
        } else {
            //很高
            dadouzhipinLei +=3;
            shucaijunzaoLei +=3;
            shuiguoLei +=3;
            jianguoLei +=3;
            yinliaoLei -=3;
            lingshilengyinLei -=3;
            naiyoulei -=3;
        }
        List<Foods> allFoods = new ArrayList<>();
        allFoods.addAll(foodsMapper.randomSelect(zhushilei+2,1));
        allFoods.addAll(foodsMapper.randomSelect(roudanLei+2,2));
        allFoods.addAll(foodsMapper.randomSelect(dadouzhipinLei+2,3));
        allFoods.addAll(foodsMapper.randomSelect(shucaijunzaoLei+2,4));
        allFoods.addAll(foodsMapper.randomSelect(shuiguoLei+2,5));
        allFoods.addAll(foodsMapper.randomSelect(naiyoulei+2,6));
        allFoods.addAll(foodsMapper.randomSelect(youzhiLei+2,7));
        allFoods.addAll(foodsMapper.randomSelect(jianguoLei+2,8));
        allFoods.addAll(foodsMapper.randomSelect(tiaoweipinLei+2,9));
        allFoods.addAll(foodsMapper.randomSelect(yinliaoLei+2,10));
        allFoods.addAll(foodsMapper.randomSelect(lingshilengyinLei+2,11));
        allFoods.addAll(foodsMapper.randomSelect(qitaLei+2,12));
        if (bmi < 19) {
            foodsDaySuggestDataDTO.setSuggestion("指标低，建议增加高热量、高营养价值的食物摄入，同时确保摄入足够的蛋白质、碳水化合物和脂肪，以提高体重和促进身体健康。以下是适合指标较低者的食物分类推荐：\n 肉蛋类：选择富含蛋白质和铁的肉类，选择富含蛋白质和铁的肉类。蛋类是优质蛋白质的来源，同时含有丰富的脂肪和维生素。\n 奶类及奶制品：奶类和奶制品是优质蛋白质和钙的来源，有助于提高体内蛋白质和钙的储备量。\n 坚果及种子：坚果和种子富含健康脂肪、蛋白质和纤维，有助于提高能量摄入和营养摄取。\n 果汁和甜点：适量摄入果汁和甜点，如新鲜果汁、坚果蜜饯等，有助于增加能量摄入。");
        } else if (bmi < 25) {
            foodsDaySuggestDataDTO.setSuggestion("指标正常，继续保持。推荐的食物分类仍然包括各种营养均衡的食物，以维持健康的体重和身体状态。以下是食物分类推荐: \n 全谷类食物：全谷类食物提供丰富的碳水化合物和纤维，有助于提供持久的能量，同时维持血糖稳定。\n 蔬菜菌藻类和水果类:蔬菜富含维生素、矿物质和纤维，有助于提供多种营养素和抗氧化物质，维持身体健康.\n 坚果类和肉蛋类：蛋白质是身体维持肌肉、组织和免疫系统健康所必需的营养素。\n 奶类：奶类及奶制品是钙的主要来源，也提供优质蛋白质和维生素D。\n 低GI食物：选择低GI（血糖指数）食物有助于维持血糖水平稳定，减少能量波动。");
        } else {
            foodsDaySuggestDataDTO.setSuggestion("指标高，注意健康饮食和运动。建议减少高热量、高脂肪的食物摄入，增加低热量、高纤维的食物摄入,多食用低热量、高纤维的食物，控制摄入高糖、高脂肪的食物，同时结合适量的运动，以达到减重和保持健康的目的。\n 推荐食物分类如下：\n 蔬菜菌藻类:该类是低热量、高纤维的食物，有助于增加饱腹感。\n水果类：水果富含维生素、矿物质和纤维，推荐选择低糖水果。\n 肉蛋类: 选择瘦肉和低脂肪的肉类,选择蛋白质含量较高、脂肪含量较低的食物 \n 大豆及制品：大豆及其制品（如豆腐、豆浆）是优质蛋白质的来源，同时也含有丰富的纤维，有助于控制饱腹感和热量摄入. \n 奶类；选择低脂或脱脂的奶制品 \n 坚果类；该类食物含有健康的脂肪和纤维，有助于增加饱腹感");
        }
       Map<Integer,Integer> map =  new HashMap<>();
        Random random = new Random();
        StringBuilder breakFast = new StringBuilder();
        for(int i = 0;i<6;i++){
            int index = random.nextInt(allFoods.size());
            if(!map.containsKey(index)){
                Foods foods = allFoods.get(index);
                breakFast.append(foods.getName()).append("(").append(foods.getCalory()).append("千卡)\n");
                map.put(index,1);
            }else{
              i--;
            }
        }
        foodsDaySuggestDataDTO.setBreakfast(breakFast.toString());
        StringBuilder lunch = new StringBuilder();
        for(int i = 0;i<8;i++){
            int index = random.nextInt(allFoods.size());
            if(!map.containsKey(index)){
                Foods foods = allFoods.get(index);
                lunch.append(foods.getName()).append("(").append(foods.getCalory()).append("千卡)\n");
                map.put(index,1);
            }else{
                i--;
            }
        }
        foodsDaySuggestDataDTO.setLunch(lunch.toString());
        StringBuilder dinner = new StringBuilder();
        for(int i = 0;i<6;i++){
            int index = random.nextInt(allFoods.size());
            if(!map.containsKey(index)){
                Foods foods = allFoods.get(index);
                dinner.append(foods.getName()).append("(").append(foods.getCalory()).append("千卡)\n");
                map.put(index,1);
            }else{
                i--;
            }
        }
        foodsDaySuggestDataDTO.setDinner(dinner.toString());
        return foodsDaySuggestDataDTO;
    }

    @Override
    public List<Foods> getList(Foods foods) {

        return foodsMapper.getList(foods);
    }

    @Override
    public Page<Foods> selectPage(Map<String,Object> params) {
        Integer pageNum = (Integer)params.get("pageNum");
        Integer pageSize = (Integer)params.get("pageSize");
        String name = (String)params.get("name");
        String category = (String)params.get("category");
        QueryWrapper<Foods> foodsQueryWrapper = new QueryWrapper<>();
        if(name !=null && name.length() > 0){
            foodsQueryWrapper.like("name",name);
        }
        if(category!=null && category.length() > 0 &&!"0".equals(category)){
            foodsQueryWrapper.eq("category",category);
        }
        return this.page(new Page<>(pageNum,pageSize),foodsQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveFood(FoodDetailVo foodsVo) {
        Foods foods = new Foods();
        String uuid = getUUID();
        foods.setFoodId(uuid);
        foods.setName(foodsVo.getName());
        foods.setCalory(foodsVo.getCalory());
        foods.setHealthLevel(Integer.parseInt(foodsVo.getHealthLight()));
        foods.setCategory(Integer.valueOf(foodsVo.getCategory()));
        boolean foodSave = this.save(foods);
        FoodsDetail foodsDetail = new FoodsDetail();
        BeanUtils.copyProperties(foodsVo,foodsDetail);
        foodsDetail.setFoodId(uuid);
        if(foodsVo.getHealthLight() == "1"){
            foodsDetail.setHealthSuggest("推荐食用");
            foodsDetail.setHealthTips("绿灯食物");
        }
        if(foodsVo.getHealthLight() == "2"){
            foodsDetail.setHealthSuggest("适量食用");
            foodsDetail.setHealthTips("黄灯食物");
        }
        if(foodsVo.getHealthLight() == "3"){
            foodsDetail.setHealthSuggest("少量食用");
            foodsDetail.setHealthTips("红灯食物");
        }

        boolean foodDetailSave = foodsDetailService.save(foodsDetail);
        return foodSave && foodDetailSave;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeFoodsById(String id) {
        boolean b = this.removeById(id);
        boolean b1 = foodsDetailService.removeById(id);
        return b && b1;
    }

    @Override
    public FoodDetailVo getFoodById(String id) {
        FoodDetailVo foodDetailVo = new FoodDetailVo();
        Foods foods = this.getById(id);
        FoodsDetail detail = foodsDetailService.getById(id);
        BeanUtils.copyProperties(detail,foodDetailVo);
        foodDetailVo.setCategory(String.valueOf(foods.getCategory()));
        foodDetailVo.setHealthLight(String.valueOf(foods.getHealthLevel()));
        return foodDetailVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateFoodsById(FoodDetailVo foodDetailVo) {
        Foods foods = new Foods();
        foods.setFoodId(foodDetailVo.getFoodId());
        foods.setCategory(Integer.valueOf(foodDetailVo.getCategory()));
        foods.setName(foodDetailVo.getName());
        foods.setCalory(foodDetailVo.getCalory());
        foods.setHealthLevel(Integer.valueOf(foodDetailVo.getHealthLight()));
        boolean b1 = this.updateById(foods);
        FoodsDetail target = new FoodsDetail();
        BeanUtils.copyProperties(foodDetailVo, target);
        target.setHealthLight(Integer.parseInt(foodDetailVo.getHealthLight()));
        if(target.getHealthLight() == 1){
            target.setHealthSuggest("推荐食用");
            target.setHealthTips("绿灯食物");
        }
        if(target.getHealthLight() == 2){
            target.setHealthSuggest("适量食用");
            target.setHealthTips("黄灯食物");
        }
        if(target.getHealthLight() == 3){
            target.setHealthSuggest("少量食用");
            target.setHealthTips("红灯食物");
        }
        boolean b = foodsDetailService.updateById(target);
        return b1 && b;
    }

    private String getUUID(){
        // 生成 UUID
        UUID uuid = UUID.randomUUID();

        // 获取 UUID 的字符串表示
        String id = uuid.toString().replace("-", "").substring(0, 16); // 取前16位
       return id;
    }
}
